/**
 * <br>JAVACC DEMO 1.0<br>
 */
package com.apache.plateform.interceptor;

import com.apache.api.vo.ResultMsg;
import com.apache.api.vo.Token;
import com.apache.exception.BusinessException;
import com.apache.license.validator.LicenseValidate;
import com.apache.tools.StrUtil;
import net.sf.json.JSONObject;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.UUID;

/**
 * description: 防止数据重复提交拦截器
 * 用法：在表里加入<input type="hidden" name="formToken" value="${formToken}" />
 * 在需要生成token的controller上增加@Token(save=true)，而在需要检查重复提交的controller上添加@Token(remove=true)就可以了
 * 如：initSave()方法上加@Token(save=true); doSave()方法上加@Token(remove=true)
 *
 * @author Hou DaYu 创建时间：下午06:26:36
 */
public class TokenInterceptor extends HandlerInterceptorAdapter {

    /**
     * 方法执行前拦截
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
            Object handler) throws Exception {

        if (handler instanceof HandlerMethod) {//方法级拦截

            boolean mark = doCheckInfo(request, response);
            if (!mark)
                return false;

            Method method = ((HandlerMethod) handler).getMethod();
            Token annotation = method.getAnnotation(Token.class);
            if (annotation != null) {
                boolean needSaveSession = annotation.save();
                if (needSaveSession) {//加入token
                    HttpSession session = request.getSession(true);
                    String uuid = UUID.randomUUID().toString();
                    if (null != session)
                        session.setAttribute("formToken", uuid);
                }
                boolean needRemoveSession = annotation.remove();
                if (needRemoveSession) {//移出token
                    if (isRepeatSubmit(request)) {
                        return false;
                    }
                    request.setAttribute("formToken",
                            request.getSession(false).getAttribute("formToken"));
                    request.getSession(false).removeAttribute("formToken");
                }
            }
            return true;
        } else {
            return super.preHandle(request, response, handler);
        }
    }

    /**
     * 判断是否重复提交
     */
    private boolean isRepeatSubmit(HttpServletRequest request) {
        String serverToken = StrUtil
                .doNull(String.valueOf(request.getSession(false).getAttribute("formToken")), "");
        if (StrUtil.isNull(serverToken)) {
            return true;
        }
        String clinetToken = request.getParameter("formToken");
        if (StrUtil.isNull(clinetToken)) {
            return true;
        }
        if (!serverToken.equals(clinetToken)) {
            return true;
        }
        return false;
    }

    /**
     * license验证
     */
    private boolean doCheckInfo(HttpServletRequest request, HttpServletResponse response)
            throws BusinessException {
        String path = request.getRequestURI();
        try {
            long lastTime = LicenseValidate.getInstance().isTimeByDay(7);//返回要提醒的天数
            if (lastTime == -1) {
                response.sendRedirect(request.getContextPath()
                        + "/errorPage?Errorcode=errorCode-00000001");//License 超过有效期！
                return false;
            } else {
                if (lastTime <= 7) {//有效期验证
                    /////////////////license将到期提醒操作////////////////////
                    warnLicenseInfo(request, response, lastTime);
                }
            }

            if (LicenseValidate.getInstance().isFormal()) {//正式license号
                if (path.indexOf("errorPage") != -1) {
                    return true;
                }
                if (!LicenseValidate.getInstance().isEffective()) {
                    String header = request.getHeader("X-Requested-With");
                    boolean isAjax = "XMLHttpRequest".equals(header) ? true : false;
                    if (isAjax) {
                        JSONObject array = JSONObject.fromObject(new ResultMsg("F", "产品授权已过期"));
                        response.setContentType("text/html;charset=utf-8");
                        PrintWriter writer = response.getWriter();
                        writer.write(array.toString());
                        writer.flush();
                        writer.close();
                    } else {
                        response.sendRedirect(request.getContextPath()
                                + "/errorPage?Errorcode=errorCode-00000002");//服务器IP或mac地址未授权
                    }
                    return false;
                }
            }
        } catch (Exception e) {
            try {//服务器IP或mac地址未授权
                if (path.indexOf("error") != -1 || path.indexOf("invalid.jsp") != -1) {
                    return true;
                }
                response.sendRedirect(request.getContextPath() + "/errorPage");
            } catch (IOException e1) {
            }
            return false;
        }
        return true;
    }

    /**
     * 提示用户license即将到期
     */
    protected void warnLicenseInfo(HttpServletRequest request, HttpServletResponse response,
            long lastTime) {
        request.getSession().setAttribute("licenseTodata", lastTime);
    }
}
